
import { _decorator, Component, director, Node, Scene, sys, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

type NodeData = {
    name: string
    position: { x: number, y: number, z: number }
    children: NodeData[];
}

//递归 序列化
function serializeNode(node: Node): NodeData {
    return {
        name: node.name,
        position: node.position.clone(),
        // 递归序列化子节点
        // children: node.children.map(serializeNode)
        children: reverser(node.children, serializeNode)
    };
}

function reverser(nodeList: Node[], fn: (node: Node) => NodeData) {
    let dataList: NodeData[] = []
    for (const n of nodeList) {
        dataList.push(fn(n));
    }
    return dataList;
}

//反序列化
function deserializeNode(nodeData: NodeData, parent) {
    let node = new Node(nodeData.name);
    node.setPosition(nodeData.position.x, nodeData.position.y);
    // 将节点添加到父节点
    parent.addChild(node);
    // 递归反序列化子节点
    nodeData.children.forEach(childData => {
        deserializeNode(childData, node);
    });

    return node;
}


function serializeScene(scene: Scene) {
    return scene.children.map(serializeNode);
}

// 反序列化整个场景
function deserializeScene(sceneData) {
    let newScene = new Scene("new");

    sceneData.forEach(nodeData => {
        deserializeNode(nodeData, newScene);
    });

    return newScene;
}

function saveScene() {
    let currentScene = director.getScene();
    let serializedData = serializeScene(currentScene);
    let jsonData = JSON.stringify(serializedData);
    sys.localStorage.setItem('sceneData', jsonData);
}

function loadScene() {
    let jsonData = sys.localStorage.getItem('sceneData');
    if (jsonData) {
        let sceneData = JSON.parse(jsonData);
        let restoredScene = deserializeScene(sceneData);
        director.runScene(restoredScene);
    }
}

@ccclass('SerializeScene')
export class SerializeScene extends Component {
    start() {
        this.scheduleOnce(() => {
            saveScene();
        }, 2)
        this.scheduleOnce(() => {
            loadScene();
        }, 6)
    }

    update(deltaTime: number) {

    }
}

